const { cpSync, existsSync, mkdirSync, readFile, writeFileSync } = require("fs");
const { join } = require("path");
const { exec } = require("child_process");
const { URL } = require("url");
const ensureDir = async (root) => {
    if (!existsSync(root)) {
        mkdirSync(root)
    }
}

const initExec = async (command, options = {}) => {
    return new Promise((resolve, reject) => {
        const root = process.cwd();
        const npmInstall = exec(command, { cwd: root, ...options })
        npmInstall.on('close', () => resolve())
        npmInstall.on('error', (e) => reject(e))
        npmInstall.stdout.pipe(process.stdout)
    })
}


async function generateUser(username, password) {
    const { encryptPassword, randomSalt } = require('@sker/core')
    // 生成salt
    const salt = randomSalt();
    const _encryptPassword = await encryptPassword(password, salt)
    // 加密password
    const user = {
        username: username,
        password: _encryptPassword,
        status: true,
        salt,
        joindate: new Date(),
        welcome_link: '/imeepos/core/web/addon',
        notice_setting: {},
        is_bind: false,
        lastvisit: new Date(),
    }
    return user;
}

/**
 * 创建权限文件
 */
const createRbacsRule = async () => {
    const root = process.cwd();
    cpSync(join(__dirname, 'rbacs/abac_model.conf'), join(root, 'rbacs/abac_model.conf'))
    cpSync(join(__dirname, 'rbacs/abac_model.csv'), join(root, 'rbacs/abac_model.csv'))
}

async function initProject() {
    const root = process.cwd();
    await ensureDir(join(root, 'addons'))
    await ensureDir(join(root, 'attachments'))
    await ensureDir(join(root, 'attachments/images'))
    await ensureDir(join(root, 'attachments/audios'))
    await ensureDir(join(root, 'attachments/videos'))
    await ensureDir(join(root, 'attachments/svgs'))
    await ensureDir(join(root, 'data'))
    await ensureDir(join(root, 'data/plugins'))
    await ensureDir(join(root, 'data/plugins/@sker'))
    await ensureDir(join(root, 'public'))
    await ensureDir(join(root, 'rbacs'))
    await ensureDir(join(root, 'prisma'))
    await createRbacsRule();
    await initExec(`npm i -g node-gyp --registry=https://registry.npmmirror.com`)
    await initExec(`pnpm i --registry=https://registry.npmmirror.com`)
    await initExec(`pnpm run argon2`)
    await initExec('pnpm run unocss:build')
    require('dotenv').config()
    // 运行升级文件
    const { cpSync } = require('fs-extra')
    cpSync(join(__dirname, 'prisma/schema.prisma'), join(root, 'prisma/schema.prisma'))
    await initExec(`prisma db pull`)
    await initExec(`prisma generate`)
    // create zapatos
    await initExec('pnpm run -r tsc')
    // install sql
    require('reflect-metadata')
    const { init, watchAddon } = require('@sker/core')
    await init()
    // 编译core模块
    await initExec('pnpm run tsc', { cwd: join(root, 'addons/@imeepos/core') })
    // 编译hasura模块
    await initExec('pnpm run tsc', { cwd: join(root, 'addons/@imeepos/hasura') })
    // 打包core模块前端文件
    await watchAddon('imeepos', 'core', false)
    await watchAddon('imeepos', 'hasura', false)
    // 插入数据库
    const { useAddon, logger } = require(`@sker/core`)
    await useAddon('post:imeepos/core/web/addon/install.post', async (addon) => {
        await addon({ name: '@imeepos/core' })
    })
    await useAddon('post:imeepos/core/web/addon/install.post', async (addon) => {
        await addon({ name: '@imeepos/hasura' })
    })
    const password = process.env.ADMIN_PASSWORD;
    if (password) {
        const { useEntityManager } = require('@sker/core')
        const { SysUser } = require('@sker/entities')
        await useEntityManager(async (m) => {
            const sysUser = await m.findOne(SysUser, { where: { username: 'admin' } })
            const user = await generateUser('admin', password)
            if (sysUser) {
                user.uid = sysUser.uid;
            }
            await m.save(SysUser, user)
        }).catch((e) => {
            // 忽略错误 数据库已有admin用户
            logger.error(e.message)
        })
    }
    // 恭喜初始化完成
    // await initExec('pnpm run start', { cwd: process.cwd() })
    console.log(`恭喜您，系统初始化完成，请用命令pnpm run start/prod 启动 然后浏览器访问 http://0.0.0.0:3102/imeepos/core/web/addon`)
}

initProject();
